package com.ocom.oauth.auth.ali;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiErrorEnum;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.codec.Base64;
import com.alipay.api.request.AlipayPlatformOpenidGetRequest;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.response.AlipayPlatformOpenidGetResponse;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.ocom.common.entity.human.EntityPersonnelInfo;
import com.ocom.common.entity.master.EntityWechatAppInfo;
import com.ocom.common.entity.master.EntityWechatPerInfo;
import com.ocom.common.resp.Result;
import com.ocom.common.vo.human.UserInfoVo;
import com.ocom.oauth.client.HumanClientService;
import com.ocom.oauth.client.PayConfigClientService;
import com.ocom.security.authentication.YoCiUser;
import com.ocom.security.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.stereotype.Service;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;

@Service
@Slf4j
public class AliUserDetailService {

    @Autowired
    HumanClientService humanClientService;
    @Autowired
    PayConfigClientService payConfigClientService;


    private static final String SERVER_URL = "https://openapi.alipay.com/gateway.do";
    private static final String FORMAT = "json";
    private static final String CHARSET = "GBK";
    private static final String GRANT_TYPE = "authorization_code";
    private static final String SIGN_TYPE = "RSA2";

    private static final String APP_ID = "2021003184688494";
    private static final String PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCo5StGv1t5At0acARoGCEeeCWehGlYuGEN9zCvj/PlSWn02HkZ599udtlYBJoMBDtV6jCKfM5gLvFMnEQx+cjOLwaKxh4227snz4vrVBzlYyT0Lm+m1qpPvNZtSGEmMiZjWMjsH//DQH6gtIbBgnkL6iu8gyJ4WpjECgSbUr5zTGpYWHSalNUo8IocUeozwYPvNWqDJ/YI78KcLIOlCujFr9MsNYlKj8f9GxLOxd1HWHSgEwFuma94kIjciPrRCvI/uUWu8BsSz+0HxYsGl45fC3zCg/egWr0iLM9gSvn5/70NbGUbCTwq9+TsAuT5Huj7KkJGOFkE0rpTFZAQ5CdDAgMBAAECggEBAJvJFovhQdxy2cLjBA2IBDR4miqG9CzTlSIumYe2fj9F4ifn7HwKtrrLgVqAlB71YE21ACUdTbbGVehWU0jNn30fPyeN6pyrPQxRkjv0j9q+An4Avxfi9aErC5Ytpv52T5ZfdKToNx/AQ4y0N4ASetiUnNb7FjZxSmu42drzDZyGomcSjoOu+d6EOBDnWOE1bAgVUea4gPUD+LEev1Kx+Du5DQ2ZWfFYphO98YoTpJ8DOvbSE3Jsezef/w+19l1nZzrW7m+MBD6Vzrr8FRAUW8pMEo+AVAw7KeYqSkD3afLX0TUXkJUyyAp1Ic3EHTDHQJLHCiJklCqQiUkuPGTmjjECgYEA7rbK/rSGpP2Q+AYOLuMTDAmYZDQevTqeT4MDzqgRLP1FZPrwsOn/oS3HXLA0DSGdlulqI9ZejME2JOlfv6LIb6wIZPhGrl6BISnwk3GntBQstLSL6mQE/A0Ie/U2dLTCPiWtRB8cBgMHdGEqlyJFtN48nzyh1HnOiAU7G4hzo4UCgYEAtSAYj922/k0kX2hHvSRs7HgRToWsTQ0B/LG2DJ6DxUMLcDBGuA/aDZogxuo6yGc4GcxSLQw+BnxjvPotnkNibhq3SLZYtU4TtJRlLIR1BinN/8d85w9UalrFeql8tC8ENKnc5s9pd4VQW+53maYT0UDVW8iJa8oWjRwyZiempicCgYEAjMPx1Fy0AVsdP4SinHd+5dxKptwtPDzy2cRSXGyzJCp931wyzsBN48fRBhFJwGyQN0uRMWzZ+Hp+6SlNMv5U37U8hf36ABzuXJYUrX2Z/RDgg/brgt5UKiWtWRtyb0OgP3GMSN1ncwwaO0CJEvI81LkwWl4wt9DUP1WGU2gVeNkCgYBYzQKdzkMAjMuvZw39ApXQndFGYS0nnaACxxINP8408XjzKQgTB9qNXqqBO6dUR57urwj/AwiJ34R6y2GAPWNNvhVsNdJqGXx5xWORHuPNAMP5ilGHazGk7xnw2JXGNWLnevxNwRThP2A1okXK8+y1ZAb29+vACBVkW5WuFfSTcwKBgC1ea+8ZNEEIuO/P9ZxEl8m+aJ2J4iC8zVdlU0k3fJlK4VsFxUaHezI88Gj36oqk4G8RRT+yYg0Vla5if2fMIMG7uNamg3bgPXfU7PLMANGxL8V0FPXaVsSl3hBFByvmNbu+mriVEU0I51PTP6/P6pAEtRxv7Nn4ry4AtxgS8K8Z";
    private static final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn+1TyyXhaKjl7E8UHIfs66bYgsAA6RH4udvqw5Bd4BurZVIkF1tQvwgGFF9dCMUJwq4uhc3CsWfG3VOBXwlYaZC3cqH1fSEUMpgW440Z5as8uzeowDyMWGwYWb+xOtwlNswIDsD7jHOEs3BRQacDTjG5g1Si/4yVy+vAf8XY1eJB9prCcRhzRNlmSQcwvTGnC1Esmeyjaa73nRPznIWaYKSNdUvtiJJ/UjSnTGGaZgalqy8hI6Wu1Dz+jVO0RvkqfRAW5VgBYKhPVhBMMdCYPZCJpanYs93ZnSTP97GdhFB/JvmlhhUpl7DgimJ4Ifw8IOhu/u4nfoYwgYdhHKoO/QIDAQAB";


    //获取用户
    public UserDetails loadByCode(String code, String comId, String encrypResponse) {
        Result result = payConfigClientService.getWxInfo(Long.valueOf(comId), 0l, "alixcx");
        if (200 != result.getCode()) {
            throw new InvalidGrantException("用户不存在!");
        }
        EntityWechatAppInfo entityWechatAppInfo = JSON.parseObject(JSON.toJSONString(result.getData()), EntityWechatAppInfo.class);

        AlipaySystemOauthTokenResponse response = new AlipaySystemOauthTokenResponse();
        UserInfoVo userInfoVo = new UserInfoVo();
        EntityWechatPerInfo entityWechatPerInfo = new EntityWechatPerInfo();

        try {
            encrypResponse = decrypt(encrypResponse, entityWechatAppInfo.getAlipayAes(), "utf-8");
            Map<String, String> map = JSON.parseObject(encrypResponse, Map.class);
            userInfoVo.setComId(Long.valueOf(comId));
            userInfoVo.setPPhone(map.get("mobile"));
            userInfoVo.setOnlyOne(true);
            Result personnelGetPersonInfoResult = humanClientService.PersonnelGetPersonInfo(userInfoVo);
            if (personnelGetPersonInfoResult.getCode() == 200) {
                AlipayClient alipayClient = new DefaultAlipayClient(SERVER_URL, entityWechatAppInfo.getAppid(), entityWechatAppInfo.getAppPrivateKey(), FORMAT, CHARSET, entityWechatAppInfo.getAlipayPublicKey(), SIGN_TYPE);
                AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
                request.setGrantType(GRANT_TYPE);
                request.setCode(code);
                response = alipayClient.execute(request);

                if (response.isSuccess()) {
                    log.info("调用成功! userId:{}, alipayUserId:{}, openId:{}, token:{}, refreshToken:{}", response.getUserId(), response.getAlipayUserId(), response.getOpenId(), response.getAccessToken(), response.getRefreshToken());
                } else {
                    log.info("失败! 响应码:{}, 响应内容:{}", response.getCode(), response.getSubMsg());
                    throw new AlipayApiException(response.getCode(), response.getSubMsg());
                }

                EntityPersonnelInfo entityPersonnelInfo = JSON.parseObject(JSON.toJSONString(personnelGetPersonInfoResult.getData()), EntityPersonnelInfo.class);

                entityWechatPerInfo.setComId(entityPersonnelInfo.getComId());
                entityWechatPerInfo.setPId(entityPersonnelInfo.getPId());
                entityWechatPerInfo.setAppid(entityWechatAppInfo.getAppid());
                entityWechatPerInfo.setOpenid(response.getUserId());
                humanClientService.addWxper(entityWechatPerInfo);
            }

        } catch (AlipayApiException alipayApiException) {
            log.info("换取授权访问令牌失败! 异常码:{}", alipayApiException.getErrMsg());
            throw new InvalidGrantException("换取授权访问令牌失败!" + alipayApiException.getErrMsg());
        } catch (Exception e) {
            e.printStackTrace();
            log.info("未知异常:{}", e.getMessage());
            throw new InvalidGrantException("未知异常!" + e.getMessage());
        }

        List<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("ROLE_ALIXCX"));//TODO

        Set<String> permissions = new HashSet<>();
        permissions.add("sys:user:admin");

        return new YoCiUser(entityWechatPerInfo.getPId(), Long.valueOf(comId), 0L, userInfoVo.getPPhone(), permissions, response.getUserId(), "N/A", true, true, true, true, authorities, new ArrayList<>());
    }


    /**
     * @param content 密文
     * @param key     aes密钥
     * @param charset 字符集
     * @return 原文
     */
    public static String decrypt(String content, String key, String charset) throws Exception {

        //反序列化AES密钥
        SecretKeySpec keySpec = new SecretKeySpec(Base64.decodeBase64(key.getBytes()), "AES");

        //128bit全零的IV向量
        byte[] iv = new byte[16];
        for (int i = 0; i < iv.length; i++) {
            iv[i] = 0;
        }
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

        //初始化加密器并加密
        Cipher deCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        deCipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec);
        byte[] encryptedBytes = Base64.decodeBase64(content.getBytes(charset));
        byte[] bytes = deCipher.doFinal(encryptedBytes);
        return new String(bytes);

    }

    public static void main(String[] args) {
        String response = "HM9kFD3ATUp0usST5n3LTu1KZS+C3ujI1hMzbCeY7alOXN1eFHCSfmyEnZR7Bo7wmC9tWAbotPrzec9FJdGPQg==";
        String key = "rsae3hvRwt3LmmK+nlabWA==";
        try {
            String content = decrypt(response, key, "utf-8");
            System.out.println(content);
            Map<String, String> map = JSON.parseObject(content, Map.class);

            System.out.println(map.get("mobile"));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
